﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using desarrolloMobile.DGTViewer.ViewModels;

namespace desarrolloMobile.DGTViewer
{
    public static class ExtensionClass
    {

        public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> enumerable)
        {
            var col = new ObservableCollection<T>();

            foreach (var cur in enumerable)
            {
                col.Add(cur);
            }

            return col;
        }

        public static IEnumerable<Incidencia> Deserialize(this Stream objeto, long lenght, bool dgt)
        {
            if (dgt) return objeto.DeserializeDGT(lenght);
            
            return objeto.DeserializeEUS(lenght);
        }

        public static IEnumerable<Incidencia> DeserializeEUS(this Stream objeto, long lenght)
        {
            var readBuffer = new byte[lenght];

            IEnumerable<Incidencia> nuevasIncidencias = null;

            objeto.BeginRead(readBuffer, 0, readBuffer.Length,
                             readAr =>
                             {
                                 var read = objeto.EndRead(readAr);
                                 
                                 var readText = Encoding.GetEncoding("ISO-8859-1")
                                     .GetString(readBuffer, 0, readBuffer.Length);

                                 nuevasIncidencias = from elemento in XDocument.Parse(readText)
                                                         .Descendants("raiz").Descendants("incidencia")
                                                     select new Incidencia
                                                     {
                                                         Autonomia =
                                                             elemento.Element(XName.Get("autonomia")).Value.Trim(),
                                                         Carretera =
                                                             elemento.Element(XName.Get("carretera")).Value.Trim(),
                                                         Causa = elemento.Element(XName.Get("causa")).Value.Trim(),
                                                         FechaHora = elemento.Element(XName.Get("fechahora_ini")).Value.Trim(),
                                                         Final = elemento.Element(XName.Get("pk_final")).Value.Trim(),
                                                         //Hacia = elemento.Element(XName.Get("hacia")).Value.Trim(),
                                                         Incial = elemento.Element(XName.Get("pk_inicial")).Value.Trim(),
                                                         Matricula =
                                                             elemento.Element(XName.Get("matricula")).Value.Trim(),
                                                         Nivel = elemento.Element(XName.Get("nivel")).Value.Trim(),
                                                         Poblacion =
                                                             elemento.Element(XName.Get("poblacion")).Value.Trim(),
                                                         Sentido = elemento.Element(XName.Get("sentido")).Value.Trim(),
                                                         Tipo = elemento.Element(XName.Get("tipo")).Value.Trim()
                                                     };
                             }, null);

            return nuevasIncidencias
                .OrderByDescending(i => DateTime.Parse(i.FechaHora))
                .Where(i => !string.IsNullOrEmpty(i.Poblacion));

        }
        public static IEnumerable<Incidencia> DeserializeDGT(this Stream objeto, long lenght)
        {
            var readBuffer = new byte[lenght];

            IEnumerable<Incidencia> nuevasIncidencias = null;

            objeto.BeginRead(readBuffer, 0, readBuffer.Length,
                             readAr =>
                             { 
                                 var read = objeto.EndRead(readAr);
                                 var readText = Encoding.UTF8
                                     .GetString(readBuffer, 0, readBuffer.Length);

                                 nuevasIncidencias = from elemento in XDocument.Parse(readText)
                                                         .Descendants("raiz").Descendants("incidencia")
                                                     select new Incidencia
                                                                {
                                                                    Autonomia =
                                                                        elemento.Element(XName.Get("autonomia")).Value.Trim(),
                                                                    Carretera =
                                                                        elemento.Element(XName.Get("carretera")).Value.Trim(),
                                                                    Causa = elemento.Element(XName.Get("causa")).Value.Trim(),
                                                                    FechaHora = elemento.Element(XName.Get("fechahora_ini")).Value.Trim(),
                                                                    Final = elemento.Element(XName.Get("pk_final")).Value.Trim(),
                                                                    Hacia = elemento.Element(XName.Get("hacia")).Value.Trim(),
                                                                    Incial = elemento.Element(XName.Get("pk_inicial")).Value.Trim(),
                                                                    Matricula =
                                                                        elemento.Element(XName.Get("matricula")).Value.Trim(),
                                                                    Nivel = elemento.Element(XName.Get("nivel")).Value.Trim(),
                                                                    Poblacion =
                                                                        elemento.Element(XName.Get("poblacion")).Value.Trim(),
                                                                    Sentido = elemento.Element(XName.Get("sentido")).Value.Trim(),
                                                                    Tipo = elemento.Element(XName.Get("tipo")).Value.Trim()
                                                                };
                             }, null);

            return nuevasIncidencias
                .OrderByDescending(i => DateTime.Parse(i.FechaHora));
        }

        public static bool IsValid(this string cadena)
        {
            return !string.IsNullOrEmpty(cadena);
        }

        public static bool IsNotValid(this string cadena)
        {
            return string.IsNullOrEmpty(cadena);
        }

        public static DgtContexto TryGetNewInstance(this DgtContexto contexto, string pValor, string pCampo, bool dgt)
        {
            if (contexto != null)
                return contexto;

            return contexto.GetNewInstance(pValor, pCampo, dgt);
        }

        public static DgtContexto GetNewInstance(this DgtContexto contexto, string pValor, string pCampo, bool dgt)
        {
            if ((pValor.IsValid()) && (pCampo.IsValid()))
            {
                Func<Incidencia, bool> p = null;

                switch (pCampo)
                {
                    case "Autonomia":
                        p = (i => i.Autonomia == pValor);
                        break;
                    case "Poblacion":
                        p = (i => i.Poblacion == pValor);
                        break;
                    case "Carretera":
                        p = (i => i.Carretera == pValor);
                        break;
                    case "Hora":
                        p = (i =>
                             DateTime.Parse(i.FechaHora) >=
                             DateTime.Now.Subtract(new TimeSpan(1, 0, 0)));
                        break;
                    case "Fecha":
                        p = (i =>
                             DateTime.Parse(i.FechaHora) >=
                             DateTime.Today.Subtract(new TimeSpan(1, 0, 0, 0)));
                        break;

                }

                return new DgtContexto(p, dgt)
                           {
                               PredicadoValor = pValor,
                               PredicadoCampo = pCampo
                           };
            }

            
            return new DgtContexto(dgt);
        }
    }
}